﻿using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using V2TEK.NET.SH.Silverlight.Charts.Core;

namespace V2TEK.NET.SH.Silverlight.Charts.GanttHelper
{
    /// <summary>
    /// 绘制甘特图
    /// </summary>
    public class TaskEntryViewer : Panel
    {
        protected AbstractTaskEntryLayout _entryLayout;
        //private TaskEntryAction _teAction;
        //private double _newXPosition;
        //private double _oldXPosition;
        public Type TaskRendererProvider = null;

        public TaskEntryViewer()
        {

        }

        public AbstractTaskEntryLayout EntryLayout
        {
            get
            {
                return _entryLayout;
            }
        }

        protected void EnsureRenderers(int count)
        {
            base.Children.Clear();
            int i = 0;
            while (i < count)
            {
                //实现IClonable接口，替代使用反射机制创建Renderer对象，性能可能会更好，暂不改进
                UIElement renderer = this.NewItemRenderer;
                TaskEntryLayoutItem item = _entryLayout.Items[i];
                (renderer as ITaskEntryRenderer).Data = item.Data;
                FrameworkElement fwe = renderer as FrameworkElement;
                fwe.HorizontalAlignment = HorizontalAlignment.Left;
                fwe.Margin = new Thickness(0d,0d,0d,0d);

                this.Children.Add(renderer);

                i++;
            }
        }

        public double BottomDelta = 0d;

        protected override Size ArrangeOverride(Size finalSize)
        {
            if (_entryLayout == null || _entryLayout.Items.Count == 0)
                return base.ArrangeOverride(finalSize);

            ObservableCollection<TaskEntryLayoutItem> items = _entryLayout.Items;
            double xPosition = _entryLayout.XPosition;//GetXPositionByAction(_teAction);
            double yPosition = _entryLayout.YPosition;
            double zoom = _entryLayout.Zoom;
            double rowHeight = _entryLayout.RowHeight;
            //double duration = Owner.MaxHScrollDuration;
            int count = items.Count;

            for (int i = 0; i < count; i++)
            {
                TaskEntryLayoutItem item = items[i];
                UIElement renderer = base.Children[i];
                double vpxs = _entryLayout.ViewPortXStart;
                if (item.X < vpxs)
                    renderer.Arrange(new Rect(new Point((vpxs - xPosition) / zoom, (item.Y - yPosition) * rowHeight - BottomDelta), renderer.DesiredSize));
                else
                    renderer.Arrange(new Rect(new Point((item.X - xPosition) / zoom, (item.Y - yPosition) * rowHeight - BottomDelta), renderer.DesiredSize));
            }

           return finalSize;
        }

        protected override Size MeasureOverride(Size availableSize)
        {
            if (_entryLayout == null || _entryLayout.Items.Count == 0)
                return new Size(availableSize.Width, _entryLayout.ViewPortHeight);

            double xPosition = _entryLayout.XPosition;//GetXPositionByAction(_teAction);
            double zoom = _entryLayout.Zoom;

            ObservableCollection<TaskEntryLayoutItem> items = _entryLayout.Items;
            int count = items.Count;

            for (int i = 0; i < count; i++)
            {
                TaskEntryLayoutItem item = items[i];
                UIElement renderer = base.Children[i];

                //去掉不能显示的部分，应该会提供绘图性能
                //renderer.Measure(new Size(item.Width / zoom, item.Height));
                double needWidth = GetMinNeedWidth(item, zoom, xPosition);
                if (needWidth > 0)
                {
                    renderer.Measure(new Size(GetMinNeedWidth(item, zoom, xPosition), item.Height));
                }
                //minX = Math.Min(item.X, minX);
                //maxXPlusWidth = Math.Max(item.X + item.Width, maxXPlusWidth);
            }

            return new Size(_entryLayout.ViewPortWidth, _entryLayout.ViewPortHeight);

            //return new Size((maxXPlusWidth - minX) / zoom, _entryLayout.ViewPortHeight);
        }

        private double GetMinNeedWidth(TaskEntryLayoutItem item, double zoom,double xPosition)
        {
            double itemXStart = item.X;
            double itemXEnd = item.X + item.Width;
            double xEnd = Math.Min(_entryLayout.ViewPortXEnd, itemXEnd);
            double xStart = Math.Max(item.X, _entryLayout.ViewPortXStart);
            return (xEnd - xStart) / zoom;
        }


        public void OnUpdate(object sender, LayoutUpdateEventArgs args)
        {
            _entryLayout = args.Layout as AbstractTaskEntryLayout;
            //_oldXPosition = _entryLayout.XPosition;
            //_teAction = TaskEntryAction.LayoutUpdate;

            EnsureRenderers(_entryLayout.Items.Count);
            this.InvalidateMeasure();
            this.InvalidateArrange();
        }

        /// <summary>
        /// 每次调用都会创建一个新的Renderer实例
        /// </summary>
        public UIElement NewItemRenderer
        {
            get
            {
                return Activator.CreateInstance(TaskRendererProvider) as UIElement;
            }
        }
    }
}
